package com.etrans.baf.analyse.task.swap.service;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.ibatis.annotations.Param;
import org.mybatis.spring.SqlSessionTemplate;
import org.quartz.utils.DBConnectionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import com.etrans.baf.analyse.util.BaseService;
import com.etrans.baf.analyse.util.Constants;
import com.etrans.baf.analyse.util.DateUtils;
import com.etrans.baf.analyse.util.SpringWebContextUtil;
import com.etrans.baf.analyse.util.Sysconfig;
import com.etrans.baf.analyse.util.TxtFileUtil;
import com.etrans.baf.analyse.util.XmlReader;
import com.mongodb.BasicDBObject;
import com.mongodb.CommandResult;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.MapReduceCommand;
import com.mongodb.MapReduceCommand.OutputType;
 
/**
 * 车辆维度中间表 业务表
 * @author liushuli
 * BaseService 继承mysql业务方法
 */

@Service
public class VehicleSwapService extends BaseService{

	@Autowired
	private MongoTemplate egovMongoTemplate;//引入配置的mongod模版
	
  	public VehicleSwapService() {
		super.masterAliases = "com.etrans.baf.analyse.task.swap.persistence.swapMapper";
  	}
	@Override
	protected SqlSessionTemplate getMasterSessionTemplate() {
		return (SqlSessionTemplate) SpringWebContextUtil.getApplicationContext().getBean("dataSourceMasterSession");
	}
  
	/**
	 * analyse_date 分析时间
	 * @throws Exception 
	 */
	public void insertVehicleSwrap(String analyse_date) throws Exception{
		Date analyseDate = DateUtils.parse(analyse_date,Constants.DATE_YYYY_MM_DD);

		List<HashMap> list = getVehicleSwrap(analyse_date);
		List<HashMap> areaList = getPrinvinceCity();
		Map<Integer, String> areaMap = new HashMap();
		for (HashMap hashMap : areaList) {
			areaMap.put(Integer.parseInt(hashMap.get("ID").toString()), String.valueOf(hashMap.get("Name")));
		}
 		List insertList = new ArrayList();
		for (HashMap veh : list) {
			DBObject db = new BasicDBObject();
			db.put("_id", veh.get("ID"));
			db.put("analyse_date",analyseDate);
			db.put("enterprise_name", veh.get("enterprise_name"));
			db.put("area_name", veh.get("area_name"));
            db.put("trade_kind_id", Integer.parseInt(String.valueOf(veh.get("trade_kind_id"))));//行业id
            db.put("vehicle_id", Integer.parseInt(String.valueOf(veh.get("vehicle_id"))));
			db.put("trade_kind", veh.get("trade_kind"));
			db.put("platform_name", veh.get("platform_name"));
            db.put("platform_id", Integer.parseInt(String.valueOf(veh.get("platform_id"))));
            db.put("enterprise_id", Integer.parseInt(String.valueOf(veh.get("enterprise_id"))));
            db.put("area_id", Integer.parseInt(String.valueOf(veh.get("area_id"))));
            db.put("gnss_centerid", Integer.parseInt(String.valueOf(veh.get("gnss_centerid"))));
            db.put("vehicle_color", Integer.parseInt(String.valueOf(veh.get("vehicle_color"))));
			db.put("vehicle_no", veh.get("vehicle_no"));
			db.put("owner_unit", veh.get("owner_unit"));
            if(veh.get("FullID")!=null){
				int privince =0;
				int city =0;
				String[] fullID = String.valueOf(veh.get("FullID")).split("\\.");
                privince = Integer.parseInt(fullID[0]);
                city = Integer.parseInt(fullID[1]);
                String pri = areaMap.get(privince);
                String cit = areaMap.get(city);
                if(pri!=null && cit!=null){
                	db.put("province_id", privince);
                	db.put("province_name", pri);
                	db.put("city_id", city);
                	db.put("city_name", cit);
                	db.put("track_normal", 0);
                	db.put("alarm_count", 0);
                	db.put("alarm_processed", 0);
                	db.put("overspeed_count", 0);
                	db.put("overspeed_processed", 0);
                	db.put("roadoffset_count", 0);
                	db.put("roadoffset_processed", 0);
                	db.put("tired_count", 0);
                	db.put("tired_processed", 0);
                	db.put("tired_duration", 0);
                	db.put("prohibit_driving_count", 0);
                	db.put("prohibit_driving_processed", 0);
                	db.put("mileage_2_5", 0);
                	db.put("nightly_3rd_count", 0);
                	db.put("nightly_3rd_processed", 0);
                	db.put("over_load_count", 0);
                	db.put("over_load_processed", 0);
                	db.put("overspeed_100_count", 0);
                	db.put("speed_160_count", 0);
                	db.put("track_complete_rate", 0);
                	db.put("data_fault_rate", 0.0);
                	db.put("data_correct_rate", 0.0);
                	db.put("has_track", false);
                	db.put("exception_track_count", 0);
                	db.put("gpstime_exception_count", 0);
                	db.put("location_exception_count", 0);
                	db.put("speed_exception_count", 0);
                	db.put("head_exception_count", 0);
                    db.put("has_net", false);
                    db.put("notrack_day_count", 0);
                    db.put("notrack_vehicle_count", 0);
                    db.put("notrack_day_month_count", 0);
                    db.put("sum_gap_time", 0.0);//不用于展示
                    db.put("sum_total_time", 0.0);//不用于展示
                	insertList.add(db);
                }
			}
		}
		if(insertList!=null && insertList.size()>0){
			Date end = DateUtils.parse(analyse_date+" 23:59:59.999",Constants.DATE_yyyy_MM_dd_HH_mm_ss_SSS);
	    	Query query = Query.query(Criteria.where("analyse_date").gte(analyseDate).lte(end));
	    	int dcount = egovMongoTemplate.remove(query, "vehicle_swap").getN();
	    	logger.info("vehicle_swap删除已经分析的数据:"+dcount+",分析日期："+analyse_date);
		    egovMongoTemplate.insert(insertList, "vehicle_swap");
		    logger.info("vehicle_swap新增"+insertList.size()+"行数据");
 			

		    String dirUrl=System.getProperty("analyse")+Sysconfig.getPropValueByCode("swap");
		    String table_date = DateUtils.format(analyseDate,Constants.DATE_YYMMDD);
		    mapReduceTrack(dirUrl,analyse_date,table_date);
		    mapReduceAlarm(dirUrl,table_date);
		    mapReduceAlarmResult(dirUrl,analyse_date,table_date);
		    mapReduceException(dirUrl, analyse_date,table_date);
		}
	}
	/**
	 * 车辆维度中间表轨迹分析 
	 * @param dirUrl
	 * @param analyse_date
	 * @param table_date
	 * @throws Exception
	 */
	private void mapReduceTrack(String dirUrl,String analyse_date,String table_date) throws Exception{
		Map<String,String> map = XmlReader.readXmlToMapReduce(dirUrl+"vehicle_swap_track.xml");
		if(map!=null&& map.size()>0){
	     	DBObject command = new BasicDBObject();
            String fin = map.get("finalize");
            Date last = new Date(DateUtils.parse(analyse_date,Constants.DATE_YYYY_MM_DD).getTime()-24*60*60*1000L);
			String last_day=DateUtils.format(last,Constants.DATE_YYYY_MM_DD);
            String fin_date = fin.replaceAll("DATE_YY_MM_DD_1STR", last_day).replaceAll("DATE_YY_MM_DD_STR",analyse_date);
        	DBObject sort = new BasicDBObject();
        	sort.put("_id", 1);
        	command.put("mapreduce","gps_info_"+table_date);
        	command.put("map",map.get("map"));
        	command.put("reduce",map.get("reduce"));
           	command.put("finalize",fin_date);
        	command.put("out","vehicle_swap_track"); 
        	command.put("sort",sort);
        	CommandResult result = egovMongoTemplate.executeCommand(command);
         
        	boolean ok = result.ok();
        	logger.info("vehcle_swap_track创建"+((ok)?"成功":"失败:原因"+result.getErrorMessage()));
        	if(ok){
        		String update = map.get("update").replaceAll("DATE_YYMMDD", table_date);
        		egovMongoTemplate.getDb().doEval(update);//追加
        	}
		}
	}
	/**
     * 车辆维度中间表异常分析
     * @param dirUrl 文件目录地址
     * @param analyse_date yyyy-MM-dd
     * @param table_date yyMMdd
     * @throws Exception
     */
	private void mapReduceException(String dirUrl,String analyse_date,String table_date) throws Exception{
		Map<String,String> exp = XmlReader.readXmlToMapReduce(dirUrl+"vehicle_swap_exception.xml");
         if(exp!=null&& exp.size()>0){
         	DBObject command = new BasicDBObject();
        	DBObject query = new BasicDBObject();
        	DBObject time = new BasicDBObject();
        	Date start = DateUtils.parse(analyse_date+" 00:00:00.000");
        	time.put("$gte",start);
        	Date end = DateUtils.parse(analyse_date+" 23:59:59.999");
        	time.put("$lte",end);
        	query.put("gps_time", time);
        	DBObject sort = new BasicDBObject();
        	sort.put("_id", 1);
        	command.put("mapreduce","gps_info_exception");
        	command.put("query",query);
        	command.put("map",exp.get("map"));
        	command.put("reduce",exp.get("reduce"));
        	command.put("out","vehicle_swap_exception"); 
        	command.put("sort",sort);
        	CommandResult result = egovMongoTemplate.executeCommand(command);
        	boolean ok = result.ok();
        	logger.info("vehcle_swap_exception创建"+((ok)?"成功":"失败:原因"+result.getErrorMessage()));
	        if(ok){//入库更新
	        	String update = exp.get("update").replaceAll("DATE_YYMMDD", table_date);
        		egovMongoTemplate.getDb().doEval(update);//追加
	        }
         }
    }
 	 
	/**
     * 车辆维度中间表报警分析
     * @param dirUrl 文件目录地址
     * @param analyse_date yyyy-MM-dd
     * @param table_date yyMMdd
     * @throws Exception
     */
	private void mapReduceAlarm(String dirUrl,String table_date) throws Exception{
		Map<String,String> exp = XmlReader.readXmlToMapReduce(dirUrl+"vehicle_swap_alarm.xml");
         if(exp!=null&& exp.size()>0){
         	DBObject command = new BasicDBObject();
        	DBObject sort = new BasicDBObject();
        	sort.put("_id",1);
        	command.put("mapreduce","alarm_info_"+table_date);
        	command.put("map",exp.get("map"));
        	command.put("reduce",exp.get("reduce"));
        	command.put("finalize",exp.get("finalize"));
        	command.put("out","vehicle_swap_alarm"); 
        	command.put("sort", sort);
        	CommandResult result = egovMongoTemplate.executeCommand(command);
        	boolean ok = result.ok();
        	logger.info("vehcle_swap_alarm创建"+((ok)?"成功":"失败:原因"+result.getErrorMessage()));
	        if(ok){//入库更新
	        	String update = exp.get("update").replaceAll("DATE_YYMMDD", table_date);
        		egovMongoTemplate.getDb().doEval(update);//追加
	        }
         }
    }
	/**
	 * 车辆维度中间表处理结果分析
	 * @param dirUrl
	 * @param table_date
	 * @throws Exception
	 */
	private void mapReduceAlarmResult(String dirUrl,String analyse_date,String table_date) throws Exception{
		Map<String,String> map = XmlReader.readXmlToMapReduce(dirUrl+"vehicle_swap_alarm_result.xml");
         if(map!=null&& map.size()>0){
         	DBObject command = new BasicDBObject();
        	DBObject sort = new BasicDBObject();
        	sort.put("_id",1);
        	DBObject query = new BasicDBObject();
        	DBObject time = new BasicDBObject();
        	Date start = DateUtils.parse(analyse_date+" 00:00:00.000");
        	time.put("$gte",start);
        	Date end = DateUtils.parse(analyse_date+" 23:59:59.999");
        	time.put("$lte",end);
        	DBObject final_result =new BasicDBObject();
        	final_result.put("$exists",true);
        	query.put("final_result",final_result);
        	DBObject info_id=new BasicDBObject();
        	info_id.put("$exists",true);
        	query.put("info_id", info_id);
        	query.put("alarm_time", time);
        	command.put("mapreduce","alarm_result");
        	command.put("query",query);
        	command.put("map",map.get("map"));
        	command.put("reduce",map.get("reduce"));
        	command.put("out","vehicle_swap_alarm_result"); 
        	command.put("sort", sort);
        	CommandResult result = egovMongoTemplate.executeCommand(command);
        	boolean ok = result.ok();
        	logger.info("vehicle_swap_alarm_result创建"+((ok)?"成功":"失败:原因"+result.getErrorMessage()));
	        if(ok){//入库更新
	        	String update = map.get("update").replaceAll("DATE_YYMMDD", table_date);
        		egovMongoTemplate.getDb().doEval(update);//追加
	        }
         }
    }
	/**
	 * 问题车辆分析入库
	 * @param analyse_date
	 * @throws Exception
	 */
	public void problemAnalyse() throws Exception{
		String last_mon = DateUtils.getAnalyseDate(null, 1).substring(0,7);
		String current_mon = DateUtils.format(new Date(),Constants.DATE_YYYY_MM);
		Query query = Query.query(Criteria.where("analyse_date").is(DateUtils.parse(current_mon+"-25",Constants.DATE_YYYY_MM_DD)));
    	int dcount = egovMongoTemplate.remove(query, "vehicle_has_problem").getN(); 
	   
		String dirUrl=System.getProperty("analyse")+Sysconfig.getPropValueByCode("swap");
		String YYMM = DateUtils.format(new Date(),Constants.DATE_YYMM);
		mapReduceProblem(dirUrl, last_mon+"-25",current_mon+"-24", YYMM,current_mon+"-24");//上个月25到这个月24号
	}
	private void mapReduceProblem(String dirUrl,String start_date,String end_date,String YYMM,String DATE_YYYY_MM_DD) throws Exception{
		Map<String,String> map = XmlReader.readXmlToMapReduce(dirUrl+"vehicle_has_problem_swap.xml");
         if(map!=null&& map.size()>0){
         	DBObject command = new BasicDBObject();
        	DBObject sort = new BasicDBObject();
        	sort.put("_id",1);
        	DBObject query = new BasicDBObject();
        	DBObject time = new BasicDBObject();
        	time.put("$gte",DateUtils.parse(start_date,Constants.DATE_YYYY_MM_DD));//大于等于25号
        	time.put("$lte",DateUtils.parse(end_date,Constants.DATE_YYYY_MM_DD));//小于等于24号
         	query.put("analyse_date", time);
        	command.put("mapreduce","vehicle_swap");
        	command.put("query",query);
        	command.put("map",map.get("map"));
        	command.put("reduce",map.get("reduce"));
        	command.put("finalize",map.get("finalize"));
        	command.put("out","vehicle_has_problem_swap_temp"); 
        	command.put("sort", sort);
        	CommandResult result = egovMongoTemplate.executeCommand(command);
        	boolean ok = result.ok();
        	logger.info("vehicle_has_problem_swap_temp创建"+((ok)?"成功":"失败:原因"+result.getErrorMessage()));
	        if(ok){//入库更新
	        	String update = map.get("update").replaceAll("DATE_YYMM", YYMM).replaceAll("DATE_YYYY_MM_DD", DATE_YYYY_MM_DD);	
        		egovMongoTemplate.getDb().doEval(update);//追加
	        }
         }
    }
	/**
	 * 车辆中间维度表的周 月 分析
	 * @param startDate 开始日期
	 * @param endDate 结束日期
	 * @param type 0周分析 1月分析
	 * @throws Exception 
	 */
	public void weekMonthAnalyse(String startDate,String endDate,int type) throws Exception{
		String dirUrl=System.getProperty("analyse")+Sysconfig.getPropValueByCode("swap");
		Map<String,String> map = XmlReader.readXmlToMapReduce(dirUrl+"vehicle_swap_weekAndMonth.xml");
	     if(map!=null){
	        	String insert_table="";
	        	String find_table="";
	        	String YYMMDD="";
	        	String YYYY_MM_DD="";
	        	if(type==Constants.VEHICLE_ANALYSE_W){
	        		insert_table="vehicle_swap_week";
	        		find_table="vehicle_swap_week_temp";
	        		YYMMDD=startDate.substring(2,10).replaceAll("-", "");
	        		YYYY_MM_DD=DateUtils.getAnalyseDate(startDate, -1);
	        	}else if(type==Constants.VEHICLE_ANALYSE_M){
	        		insert_table="vehicle_swap_month";
	        		find_table="vehicle_swap_month_temp";
	        		
	        		String start=endDate.substring(0,7)+"-01";
	        		YYMMDD=start.substring(2,10).replaceAll("-", "");
	        		YYYY_MM_DD=DateUtils.getAnalyseDate(start, -1);//月的第一天
	        	}else if(type==Constants.VEHICLE_ANALYSE_CM){//当前月实时数据
	        		insert_table="vehicle_swap_curMonth";
	        		find_table="vehicle_swap_curMonth_temp";
	        		String current_mon_day = DateUtils.format(new Date(),Constants.DATE_YYYY_MM_DD);
	    			String day = current_mon_day.substring(current_mon_day.length()-2,current_mon_day.length());
	    			if(Integer.parseInt(day)<=25){//当前月
	    				String start=endDate.substring(0,7)+"-01";
		        		YYMMDD=start.substring(2,10).replaceAll("-", "");
		        		YYYY_MM_DD=DateUtils.getAnalyseDate(start, -1);//月的第一天
	    			}else{//分析下个月
	    				String  startDateStr=DateUtils.nextMonthFirstDate();
	    				YYMMDD=startDateStr.substring(2,10).replaceAll("-", "");
		        		YYYY_MM_DD=DateUtils.getAnalyseDate(startDateStr, -1);//月的第一天
	    			}
	        	}
	        	DBObject command = new BasicDBObject();
	        	DBObject sort = new BasicDBObject();
	        	sort.put("_id",1);
	        	DBObject query = new BasicDBObject();
	        	DBObject time = new BasicDBObject();
	        	time.put("$gte",DateUtils.parse(startDate,Constants.DATE_YYYY_MM_DD));//大于等于25号
	        	time.put("$lte",DateUtils.parse(endDate,Constants.DATE_YYYY_MM_DD));//小于等于24号
	         	query.put("analyse_date", time);
	        	command.put("mapreduce","vehicle_swap");
	        	command.put("query",query);
	        	command.put("map",map.get("map"));
	        	command.put("reduce",map.get("reduce"));
	        	command.put("finalize",map.get("finalize"));
	        	command.put("out",find_table); 
	        	command.put("sort", sort);
	        	CommandResult result = egovMongoTemplate.executeCommand(command);
	        	boolean ok = result.ok();
	        	logger.info(find_table+"创建"+((ok)?"成功":"失败:原因"+result.getErrorMessage()));
		        if(ok){//入库更新
		        	String update = map.get("update").replaceAll("INSERT_TABLE", insert_table).replaceAll("TABLE_PARAM", find_table).replaceAll("YYMMDD", YYMMDD).replaceAll("YYYY-MM-DD", YYYY_MM_DD);	
	        		egovMongoTemplate.getDb().doEval(update);//追加
		        }
	        }
	}
	/**
	 * 获取车辆 颜色 业务 区域等基础信息
	 * @return
	 */
	public List<HashMap> getVehicleSwrap(String analyse_date){
		return (List<HashMap>) this.select("getVehicleSwrap", analyse_date);
	}
	
	public List<HashMap> getPrinvinceCity(){
		return (List<HashMap>) this.select("getPrinvinceCity", null);
	}
	 

}
